const koa = require("koa2");
const router = require("koa-router")();
// CORS是一个W3C标准，全称是"跨域资源共享"（Cross-origin resource sharing）。
// 下面以koa2-cors为例，
const cors = require("koa2-cors");
const path = require("path");
const contentF = require("./util/content");
const mimes = require("./util/mimes");

const app = new koa();
// app.use(cors()); // 全部允许跨域
const staticPath = "./static";

// 解析资源类型
function parseMime(url) {
  let extName = path.extname(url);
  extName = extName ? extName.slice(1) : "unknown";
  return mimes[extName];
}

async function getContentAndMime(ctx) {
  // 静态资源目录在本地的绝对路径
  let fullStaticPath = path.join(__dirname, staticPath);

  // 获取静态资源内容，有可能是文件内容，目录，或404
  let content = await contentF(ctx, fullStaticPath);
  // 解析请求内容的类型
  let mime = parseMime(ctx.url);

  if (mime) {
    ctx.type = mime;
  }
  return {
    content,
    mime,
  };
}



app.use(
  cors({
    origin: function (ctx) {
      console.log(ctx.url);
      if (ctx.url.indexOf("/api") !== -1) {
        return "*"; // *是指允许来自所有域名请求
      }
      return "http://localhost:10001"; // 允许 10001 这个地址访问服务
    },
    maxAge: 5, // 预检请求的有效期，单位为秒。
    credentials: true, // 是否允许发送 Cookie
    allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    allowHeaders: ["Content-Type", "Authorization", "Accept"],
    exposeHeaders: ["UFO-Authenticate", "P-Authorization"], // 其他自定义字段
  })
);


app.use(async (ctx, next) => {
  const { mime, content } = await getContentAndMime(ctx);

  // 输出静态资源内容
  if (mime && mime.indexOf("image/") >= 0) {
    // 如果是图片，则用node原生res，输出二进制数据
    ctx.res.writeHead(200);
    ctx.res.write(content, "binary");
    ctx.res.end();
  } else {
    // 其他则输出文本
    ctx.body = content;
  }
  await next();
});

// app.use(cors({})) 干了什么
/*
app.use(async (ctx, next) => {
    // 允许来自所有域名请求
    ctx.set("Access-Control-Allow-Origin", "*");
    // 只允许 http://localhost:8080 这个域名的请求
    // ctx.set("Access-Control-Allow-Origin", "http://localhost:8080");
 
    // 设置所允许的HTTP请求方法
    ctx.set("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE");
 
    // 字段是必需的。它也是一个逗号分隔的字符串，表明服务器支持的所有头信息字段.
    ctx.set("Access-Control-Allow-Headers", "x-requested-with, accept, origin, content-type");
 
    // 服务器收到请求以后，检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后，确认允许跨源请求，就可以做出回应。
 
    // Content-Type表示具体请求中的媒体类型信息
    ctx.set("Content-Type", "application/json;charset=utf-8");
 
    // 该字段可选。它的值是一个布尔值，表示是否允许发送Cookie。默认情况下，Cookie不包括在CORS请求之中。
    // 当设置成允许请求携带cookie时，需要保证"Access-Control-Allow-Origin"是服务器有的域名，而不能是"*";
    ctx.set("Access-Control-Allow-Credentials", true);
 
    // 该字段可选，用来指定本次预检请求的有效期，单位为秒。
    // 当请求方法是PUT或DELETE等特殊方法或者Content-Type字段的类型是application/json时，服务器会提前发送一次请求进行验证
    // 下面的的设置只本次验证的有效时间，即在该时间段内服务端可以不用进行验证
    ctx.set("Access-Control-Max-Age", 300);
 
    // CORS请求时，XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段：
    //     Cache-Control、
    //     Content-Language、
    //     Content-Type、
    //     Expires、
    //     Last-Modified、
    //     Pragma。
    // 需要获取其他字段时，使用Access-Control-Expose-Headers，
    // getResponseHeader('myData')可以返回我们所需的值
    ctx.set("Access-Control-Expose-Headers", "myData");
 
    await next();
})
*/

async function delayer(time = 2000) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(111);
    }, time);
  });
}

router.post("/api/test1", async function (ctx) {
  ctx.body = JSON.stringify({ data: "success post" });
});
router.get("/api/test1", async function (ctx) {
  ctx.body = JSON.stringify({ data: "success get" });
});
router.get("/css/slow2.css", async (ctx, next) => {
  const a = await delayer(3000);
  const { content } = await getContentAndMime(ctx);
  ctx.body = content;
  await next();
});

app.use(router.routes());
app.use(router.allowedMethods());

app.listen(10001);
